{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Transformer_Torch.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "metadata": {
        "id": "g831xANXh2HY",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# http://pytorch.org/\n",
        "from os.path import exists\n",
        "from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag\n",
        "platform = '{}{}-{}'.format(get_abbr_impl(), get_impl_ver(), get_abi_tag())\n",
        "cuda_output = !ldconfig -p|grep cudart.so|sed -e 's/.*\\.\\([0-9]*\\)\\.\\([0-9]*\\)$/cu\\1\\2/'\n",
        "accelerator = cuda_output[0] if exists('/dev/nvidia0') else 'cpu'"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "nNemnO18h6PV",
        "colab_type": "code",
        "outputId": "eb6fcec1-b1b1-4a3b-93eb-9b384c30804c",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1691
        }
      },
      "cell_type": "code",
      "source": [
        "'''\n",
        "  code by Tae Hwan Jung(Jeff Jung) @graykode\n",
        "  Reference : https://github.com/jadore801120/attention-is-all-you-need-pytorch\n",
        "              https://github.com/JayParks/transformer\n",
        "'''\n",
        "import numpy as np\n",
        "import torch\n",
        "import torch.nn as nn\n",
        "import torch.optim as optim\n",
        "from torch.autograd import Variable\n",
        "import torch.nn.functional as F\n",
        "import matplotlib.pyplot as plt\n",
        "\n",
        "dtype = torch.FloatTensor\n",
        "# S: Symbol that shows starting of decoding input\n",
        "# E: Symbol that shows starting of decoding output\n",
        "# P: Symbol that will fill in blank sequence if current batch data size is short than time steps\n",
        "sentences = ['ich mochte ein bier P', 'S i want a beer', 'i want a beer E']\n",
        "\n",
        "# Transformer Parameters\n",
        "src_vocab = {'PAD' : 0}\n",
        "for i, w in enumerate(sentences[0].split()):\n",
        "    src_vocab[w] = i+1\n",
        "src_vocab_size = len(src_vocab)\n",
        "\n",
        "tgt_vocab = {'PAD' : 0}\n",
        "number_dict = {0 : 'PAD'}\n",
        "for i, w in enumerate(set((sentences[1]+' '+sentences[2]).split())):\n",
        "    tgt_vocab[w] = i+1\n",
        "    number_dict[i+1] = w\n",
        "tgt_vocab_size = len(tgt_vocab)\n",
        "\n",
        "src_len = 5\n",
        "tgt_len = 5\n",
        "\n",
        "d_model = 512  # Embedding Size\n",
        "d_ff = 2048 # FeedForward dimension\n",
        "d_k = d_v = 64  # dimension of K(=Q), V\n",
        "n_layers = 6  # number of Encoder of Decoder Layer\n",
        "n_heads = 8  # number of heads in Multi-Head Attention\n",
        "\n",
        "def make_batch(sentences):\n",
        "    input_batch = [[src_vocab[n] for n in sentences[0].split()]]\n",
        "    output_batch = [[tgt_vocab[n] for n in sentences[1].split()]]\n",
        "    target_batch = [[tgt_vocab[n] for n in sentences[2].split()]]\n",
        "    return Variable(torch.LongTensor(input_batch)), Variable(torch.LongTensor(output_batch)), Variable(torch.LongTensor(target_batch))\n",
        "\n",
        "def get_sinusoid_encoding_table(n_position, d_model):\n",
        "    def cal_angle(position, hid_idx):\n",
        "        return position / np.power(10000, 2 * (hid_idx // 2) / d_model)\n",
        "    def get_posi_angle_vec(position):\n",
        "        return [cal_angle(position, hid_j) for hid_j in range(d_model)]\n",
        "\n",
        "    sinusoid_table = np.array([get_posi_angle_vec(pos_i) for pos_i in range(n_position)])\n",
        "    sinusoid_table[:, 0::2] = np.sin(sinusoid_table[:, 0::2])  # dim 2i\n",
        "    sinusoid_table[:, 1::2] = np.cos(sinusoid_table[:, 1::2])  # dim 2i+1\n",
        "    return torch.FloatTensor(sinusoid_table)\n",
        "\n",
        "def get_attn_pad_mask(seq_q, seq_k):\n",
        "    batch_size, len_q = seq_q.size()\n",
        "    batch_size, len_k = seq_k.size()\n",
        "    # eq(zero) is PAD token\n",
        "    pad_attn_mask = seq_k.data.eq(0).unsqueeze(1)  # batch_size x 1 x len_k(=len_q), one is masking\n",
        "    return pad_attn_mask.expand(batch_size, len_q, len_k)  # batch_size x len_q x len_k\n",
        "\n",
        "def get_attn_subsequent_mask(seq):\n",
        "    attn_shape = [seq.size(0), seq.size(1), seq.size(1)]\n",
        "    subsequent_mask = np.triu(np.ones(attn_shape), k=1)\n",
        "    subsequent_mask = torch.from_numpy(subsequent_mask).byte()\n",
        "    return subsequent_mask\n",
        "\n",
        "class ScaledDotProductAttention(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(ScaledDotProductAttention, self).__init__()\n",
        "\n",
        "    def forward(self, Q, K, V, attn_mask):\n",
        "        scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) # scores : [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]\n",
        "        scores.masked_fill_(attn_mask, -1e9) # Fills elements of self tensor with value where mask is one.\n",
        "        attn = nn.Softmax(dim=-1)(scores)\n",
        "        context = torch.matmul(attn, V)\n",
        "        return context, attn\n",
        "\n",
        "class MultiHeadAttention(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(MultiHeadAttention, self).__init__()\n",
        "        self.W_Q = nn.Linear(d_model, d_k * n_heads)\n",
        "        self.W_K = nn.Linear(d_model, d_k * n_heads)\n",
        "        self.W_V = nn.Linear(d_model, d_v * n_heads)\n",
        "    def forward(self, Q, K, V, attn_mask):\n",
        "        # q: [batch_size x len_q x d_model], k: [batch_size x len_k x d_model], v: [batch_size x len_k x d_model]\n",
        "        residual, batch_size = Q, Q.size(0)\n",
        "        # (B, S, D) -proj-> (B, S, D) -split-> (B, S, H, W) -trans-> (B, H, S, W)\n",
        "        q_s = self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2)  # q_s: [batch_size x n_heads x len_q x d_k]\n",
        "        k_s = self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2)  # k_s: [batch_size x n_heads x len_k x d_k]\n",
        "        v_s = self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2)  # v_s: [batch_size x n_heads x len_k x d_v]\n",
        "\n",
        "        attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1) # attn_mask : [batch_size x n_heads x len_q x len_k]\n",
        "\n",
        "        # context: [batch_size x n_heads x len_q x d_v], attn: [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]\n",
        "        context, attn = ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask)\n",
        "        context = context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v) # context: [batch_size x len_q x n_heads * d_v]\n",
        "        output = nn.Linear(n_heads * d_v, d_model)(context)\n",
        "        return nn.LayerNorm(d_model)(output + residual), attn # output: [batch_size x len_q x d_model]\n",
        "\n",
        "class PoswiseFeedForwardNet(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(PoswiseFeedForwardNet, self).__init__()\n",
        "        self.conv1 = nn.Conv1d(in_channels=d_model, out_channels=d_ff, kernel_size=1)\n",
        "        self.conv2 = nn.Conv1d(in_channels=d_ff, out_channels=d_model, kernel_size=1)\n",
        "\n",
        "    def forward(self, inputs):\n",
        "        residual = inputs # inputs : [batch_size, len_q, d_model]\n",
        "        output = nn.ReLU()(self.conv1(inputs.transpose(1, 2)))\n",
        "        output = self.conv2(output).transpose(1, 2)\n",
        "        return nn.LayerNorm(d_model)(output + residual)\n",
        "\n",
        "class EncoderLayer(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(EncoderLayer, self).__init__()\n",
        "        self.enc_self_attn = MultiHeadAttention()\n",
        "        self.pos_ffn = PoswiseFeedForwardNet()\n",
        "\n",
        "    def forward(self, enc_inputs, enc_self_attn_mask):\n",
        "        enc_outputs, attn = self.enc_self_attn(enc_inputs, enc_inputs, enc_inputs, enc_self_attn_mask) # enc_inputs to same Q,K,V\n",
        "        enc_outputs = self.pos_ffn(enc_outputs) # enc_outputs: [batch_size x len_q x d_model]\n",
        "        return enc_outputs, attn\n",
        "\n",
        "class DecoderLayer(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(DecoderLayer, self).__init__()\n",
        "        self.dec_self_attn = MultiHeadAttention()\n",
        "        self.dec_enc_attn = MultiHeadAttention()\n",
        "        self.pos_ffn = PoswiseFeedForwardNet()\n",
        "\n",
        "    def forward(self, dec_inputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask):\n",
        "        dec_outputs, dec_self_attn = self.dec_self_attn(dec_inputs, dec_inputs, dec_inputs, dec_self_attn_mask)\n",
        "        dec_outputs, dec_enc_attn = self.dec_enc_attn(dec_outputs, enc_outputs, enc_outputs, dec_enc_attn_mask)\n",
        "        dec_outputs = self.pos_ffn(dec_outputs)\n",
        "        return dec_outputs, dec_self_attn, dec_enc_attn\n",
        "\n",
        "class Encoder(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(Encoder, self).__init__()\n",
        "        self.src_emb = nn.Embedding(src_vocab_size, d_model)\n",
        "        self.pos_emb = nn.Embedding.from_pretrained(get_sinusoid_encoding_table(src_len+1 , d_model),freeze=True)\n",
        "        self.layers = nn.ModuleList([EncoderLayer() for _ in range(n_layers)])\n",
        "\n",
        "    def forward(self, enc_inputs): # enc_inputs : [batch_size x source_len]\n",
        "        enc_outputs = self.src_emb(enc_inputs) + self.pos_emb(torch.LongTensor([[1,2,3,4,5]]))\n",
        "        enc_self_attn_mask = get_attn_pad_mask(enc_inputs, enc_inputs)\n",
        "        enc_self_attns = []\n",
        "        for layer in self.layers:\n",
        "            enc_outputs, enc_self_attn = layer(enc_outputs, enc_self_attn_mask)\n",
        "            enc_self_attns.append(enc_self_attn)\n",
        "        return enc_outputs, enc_self_attns\n",
        "\n",
        "class Decoder(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(Decoder, self).__init__()\n",
        "        self.tgt_emb = nn.Embedding(tgt_vocab_size, d_model)\n",
        "        self.pos_emb = nn.Embedding.from_pretrained(get_sinusoid_encoding_table(tgt_len+1 , d_model),freeze=True)\n",
        "        self.layers = nn.ModuleList([DecoderLayer() for _ in range(n_layers)])\n",
        "\n",
        "    def forward(self, dec_inputs, enc_inputs, enc_outputs): # dec_inputs : [batch_size x target_len]\n",
        "        dec_outputs = self.tgt_emb(dec_inputs) + self.pos_emb(torch.LongTensor([[1,2,3,4,5]]))\n",
        "        dec_self_attn_pad_mask = get_attn_pad_mask(dec_inputs, dec_inputs)\n",
        "        dec_self_attn_subsequent_mask = get_attn_subsequent_mask(dec_inputs)\n",
        "        dec_self_attn_mask = torch.gt((dec_self_attn_pad_mask + dec_self_attn_subsequent_mask), 0)\n",
        "\n",
        "        dec_enc_attn_mask = get_attn_pad_mask(dec_inputs, enc_inputs)\n",
        "\n",
        "        dec_self_attns, dec_enc_attns = [], []\n",
        "        for layer in self.layers:\n",
        "            dec_outputs, dec_self_attn, dec_enc_attn = layer(dec_outputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask)\n",
        "            dec_self_attns.append(dec_self_attn)\n",
        "            dec_enc_attns.append(dec_enc_attn)\n",
        "        return dec_outputs, dec_self_attns, dec_enc_attns\n",
        "\n",
        "class Transformer(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(Transformer, self).__init__()\n",
        "        self.encoder = Encoder()\n",
        "        self.decoder = Decoder()\n",
        "        self.projection = nn.Linear(d_model, tgt_vocab_size, bias=False)\n",
        "    def forward(self, enc_inputs, dec_inputs):\n",
        "        enc_outputs, enc_self_attns = self.encoder(enc_inputs)\n",
        "        dec_outputs, dec_self_attns, dec_enc_attns = self.decoder(dec_inputs, enc_inputs, enc_outputs)\n",
        "        dec_logits = self.projection(dec_outputs) # dec_logits : [batch_size x src_vocab_size x tgt_vocab_size]\n",
        "        return dec_logits.view(-1, dec_logits.size(-1)), enc_self_attns, dec_self_attns, dec_enc_attns\n",
        "\n",
        "model = Transformer()\n",
        "\n",
        "criterion = nn.CrossEntropyLoss()\n",
        "optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
        "\n",
        "for epoch in range(100):\n",
        "    optimizer.zero_grad()\n",
        "    enc_inputs, dec_inputs, target_batch = make_batch(sentences)\n",
        "    outputs, enc_self_attns, dec_self_attns, dec_enc_attns = model(enc_inputs, dec_inputs)\n",
        "    loss = criterion(outputs, target_batch.contiguous().view(-1))\n",
        "    if (epoch + 1) % 20 == 0:\n",
        "        print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))\n",
        "    loss.backward()\n",
        "    optimizer.step()\n",
        "\n",
        "def showgraph(attn):\n",
        "    attn = attn[-1].squeeze(0)[0]\n",
        "    attn = attn.squeeze(0).data.numpy()\n",
        "    fig = plt.figure(figsize=(n_heads, n_heads)) # [n_heads, n_heads]\n",
        "    ax = fig.add_subplot(1, 1, 1)\n",
        "    ax.matshow(attn, cmap='viridis')\n",
        "    ax.set_xticklabels(['']+sentences[0].split(), fontdict={'fontsize': 14}, rotation=90)\n",
        "    ax.set_yticklabels(['']+sentences[2].split(), fontdict={'fontsize': 14})\n",
        "    plt.show()\n",
        "\n",
        "# Test\n",
        "predict, _, _, _ = model(enc_inputs, dec_inputs)\n",
        "predict = predict.data.max(1, keepdim=True)[1]\n",
        "print(sentences[0], '->', [number_dict[n.item()] for n in predict.squeeze()])\n",
        "\n",
        "print('first head of last state enc_self_attns')\n",
        "showgraph(enc_self_attns)\n",
        "\n",
        "print('first head of last state dec_self_attns')\n",
        "showgraph(dec_self_attns)\n",
        "\n",
        "print('first head of last state dec_enc_attns')\n",
        "showgraph(dec_enc_attns)"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Epoch: 0020 cost = 0.000062\n",
            "Epoch: 0040 cost = 0.000020\n",
            "Epoch: 0060 cost = 0.000009\n",
            "Epoch: 0080 cost = 0.000008\n",
            "Epoch: 0100 cost = 0.000007\n",
            "ich mochte ein bier P -> ['i', 'want', 'a', 'beer', 'E']\n",
            "first head of last state enc_self_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeYAAAH2CAYAAAClRS9UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAHJpJREFUeJzt3XuQ1wW9//H3LhdxSqFRkICAUsLm\neOGiwp4oiLCd0DiUWAdFakvBmtTExBXHPKQCllmp2XhSD2olXqAzx0sgkpalWd5GMAGXFrmFEQd1\nlrgo+/394bjnxwDxRRY+7y89Hn/tfr57ee0Os0++n+93P1tVKpVKAQCkUF30AADg/wgzACQizACQ\niDADQCLCDACJCDMAJCLMAJCIMANAIsJMxXjjjTfinnvuiR/+8Ictx5YvX17cIIB9QJipCE8++WQM\nGzYsfvrTn8Ytt9wSERGrV6+Oz372s/HYY48VOw6gFQkzFeG73/1uXHrppfE///M/UVVVFRER3bt3\nj2uvvXa7e9AAlU6YqQh//vOf43Of+1xEREuYIyI+8YlPOJ0NHFCEmYrQpUuXWLVq1Q7Hn3vuuTjk\nkEMKWASwb7QtegCUY9SoUTFhwoQYP358NDc3x9y5c2Px4sVx1113xfjx44ueB9BqqvzZRypBqVSK\n22+/Pe67775YsWJFdOjQIXr27Bljx46N0047reh5AK1GmKkIr7zySvTq1WuH41u3bo2FCxfGwIED\nC1gF0Po8xkxFGDVq1E6P//3vf4+zzz57P68B2Hc8xkxq99xzT9x9993x5ptvxpgxY3a4/W9/+1t0\n6tSpgGUA+4Ywk9qnP/3p6NixY0yaNCmGDRu2w+0HHXRQjBgxYv8PA9hHPMZMRXjwwQfjlFNOKXoG\nwD4nzFSM559/PhoaGmLLli073HbmmWcWsAig9QkzFeHqq6+OO++8Mw477LA46KCDtrutqqoqFixY\nUNAygNYlzFSE/v37x4033hgf/ehHi54CsE/5dSkqwiGHHBInnnhi0TMA9jlhpiKcf/75cdttt4UT\nPMCBzqls0jrttNO2+0tSK1eujDZt2sT73//+7Y5HRNx33337ex7APuH3mEnrE5/4RNETAPY795ip\nKNu2bYs2bdpERMSmTZvi4IMPLngRQOvyGDMVYfny5fGZz3wm5s+f33LsrrvuilNPPTVeeeWVApcB\ntC5hpiJMnTo1TjrppKipqWk5dvrpp8fHPvaxmDp1aoHLAFqXU9lUhIEDB8ZTTz0Vbdtu/7SIN998\nMwYPHhzPPPNMQctg11atWhU9evQoegYVxj1mKkLHjh2joaFhh+MLFy6M9773vQUsgt0bNWpUbNu2\nregZVBjPyqYijB8/Purq6mLkyJHRo0ePaG5ujsbGxpg7d25cfPHFRc+DnTrzzDPj+uuvj3POOcd/\nICmbU9lUjEceeSTmzJkTK1eujKqqqvjABz4Qp512WgwfPrzoabBTn/70p+Nvf/tbbNy4Md773ve2\n/EbBO5588smClpGZMAPsI7/4xS/+4e2f/exn99MSKokwUzHmzJkTDz30UKxevTqqqqqiZ8+ecdpp\np8XJJ59c9DTYrTfffDPatWtX9AwqgMeY94Ft27bF1q1bdzjuYhjv3k033RS33357jBw5MoYMGRIR\nEX/+85+jvr4+Nm7cGKNHjy54YeV69dVXY+bMmbFs2bLYvHnzDrffcccdBaw6MGzdujV+9KMfxezZ\ns+P111+PhQsXRlNTU1x11VVx+eWXx3ve856iJ5KQMLeiJ598MqZOnRorVqzY6R9beOmllwpYdWC4\n99574+abb45+/fptd3zUqFExdepUYd4LF154Ybz22msxaNCg6NChQ9FzDihXX311vPjii/Gtb30r\nvvnNb0ZERHNzc2zYsCGmTZsWV199dcELyUiYW9Gll14aNTU1MWXKFD/gWtlrr70Wxx577A7H+/fv\nH6tXry5g0YHjpZdeikcffTQ6depU9JQDzsMPPxy/+MUvomvXri1/eOXQQw+N6dOnx6hRowpeR1bC\n3Ipef/31mDp1arRv377oKQec3r17x4IFC+JTn/rUdscfffRRF3DYS7179/a7tvvItm3bonPnzjsc\nb9++fWzcuLGARVQCYW5Fw4cPj8WLF8dxxx1X9JQDznnnnRfnnXdeDBo0KI488siIePsx5qeeeiqm\nT59e8LrKdvHFF8dll10WX/jCF6J79+5RXb39dYeOOuqogpZVvn/5l3+Jn/zkJ3Huuee2HNu4cWPM\nmDHDzwl2ybOy99LPfvazlpc3bdoUs2fPjmHDhu30XtyZZ565P6cdcJYuXRqzZ8+OlStXxtatW6Nn\nz54xevRoP+D20tFHH73DsaqqqiiVSlFVVeW5EXth6dKlcfbZZ8dbb70VGzZsiA996EOxevXq6Ny5\nc9x0003Rp0+foieSkDDvpXIvblFVVRULFizYx2tgz+3uMfru3bvvpyUHps2bN8ejjz4aK1eujA4d\nOkSvXr1iyJAhO1xsBN4hzFSEVatWxcyZM+OVV16JLVu27HC7X+kBDhQeY25FpVIpZs6cGQMGDIjj\njz8+IiLmzZsXq1atirq6uh0eu6N8559/frz55ptx0kkneXJdKxg2bFg89thjERExePDglmcM74zL\nRu4Z31v2ljC3ou985zvxyCOPxAknnNBy7PDDD48bbrgh1q9fH5MnTy5wXWVrbGyM3/72ty7I0Eou\nvPDClpcvueSSiIj4+9//Hu3bt9/hT2uyZ3b1vW3Xrl2sW7cuunTp4nu8l5YtWxaPPfZYtGnTJkaM\nGHHA/WaGU9mtaMiQITF79uw44ogjtjv+6quvxpgxY+Lxxx8vaFnlO/fcc+PrX/96HHPMMUVPOeC8\n9tprceWVV8bcuXOjqqoqFi1aFP/7v/8bF1xwQXzve9+LLl26FD2xYq1ZsyYuueSSeOaZZ6JUKkWp\nVIq2bdvG0KFD44orrvC9fReeeOKJmDhxYvTu3Tuam5tjzZo1cdttt0X//v2LntZqhLkVnXDCCfHr\nX/96h3t1r732WgwfPjyeffbZgpZVvrVr10ZdXV185CMfiSOOOGKH04PORrx7F110UTQ1NcX5558f\nY8eOjRdeeCE2b94c3/72t6OpqSmuv/76oidWrLPOOivatWsXX/7yl6Nnz55RKpXilVdeidtvvz1K\npVLcdtttRU+sOGPHjo1TTjklxo0bFxERd955Zzz88MNx5513Frys9Tif0oqGDBkSl156aUycODG6\nd+/e8jeDb7rpphg2bFjR8yraZZddFmvXro1DDz001q1bt91t/+gxPHbvN7/5TcyfPz86derU8r3s\n0KFDTJkyJUaMGFHwusq2aNGiePzxx7f7W8y9evWKAQMGxMc//vECl1WuhoaG+PznP9/y+pgxY+LG\nG28scFHrE+ZWdMUVV8Rll10Wp59+estpq+rq6hgxYkRceeWVRc+raE8//XQ89NBDfnVnH2jbtu1O\nLyG7devWnT4DnvL17NkzmpqatgtzxNvXPPBv+d3ZunXrdk8APfjgg3f6x1cqmTDvpWXLlrVciWr9\n+vUxadKklmdgv/MoQadOneIvf/mLKyjthT59+sRBBx1U9IwDUv/+/eOaa65p+SMLERErVqyIq666\nKmpqagpcVpkaGhpaXq6rq4tJkybFGWecEUceeWRUVVVFY2Nj3HXXXfG1r32twJVk5jHmvXTcccfF\nCy+8EBFvX0FpZ6dVXUFp7z3wwAMxa9asOOWUU6Jr1647/OrZ0KFDC1pW+dauXRtf/epXY+nSpbFt\n27bo0KFDbNmyJU444YS49tprd3gyI//YOz8Hdvej1c+Ed+eYY46JKVOmbPf9nT59+g7HKvlKi8K8\nl9asWRPdunWLCFdQ2pd2dtnId/gB1zoWLlwYK1eujIMOOih69erlDM+7tCd/7czPhD1XztUWK/1K\ni8IMAIm4FBUAJCLMAJCIMANAIsIMAIkIMwAkUnEXGOl9x4yiJ5Rt3me+ErX331r0jLL1vW5j0RPK\ndvN9X4+JYyrnMny/nDur6AllqzrswSitP6XoGWWr7dav6All+88XvhcTjruo6Blla5xWOReYeegr\n42PkrZXzd9kb6ift8jb3mPehvu/rXPSEA1bvo1z0Yl+pavfhoiccsD54TM+iJxywPtz58KIntBph\nBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhE\nmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIJFUYV69enUce+yx0dDQUPQUAChE\n26IH/P+6d+8eCxcuLHoGABQm1T1mAPhnlyrMq1atir59+8bSpUuLngIAhUgVZgD4Z1dVKpVKRY94\nx6pVq+KTn/xk3H///fHhD394p2+zZMO66Pu+zvt5GQDsH6me/FWO2vtvLXpC2ZaPr4/ed8woekbZ\n+l63segJZZv3/JVR2+/yomeU7ZdzZxU9oWzVXV+O5rV9ip5Rttpu/YqeULb5zffGydWnFz2jbI3T\naoqeULaG+klx1Izrip5Rtob6Sbu8zalsAEhEmAEgEWEGgESEGQASSfXkrx49esSSJUuKngEAhXGP\nGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYA\nSESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASAR\n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\nFubjjz8+vvSlL0VdXV3U1tZGu3btYtq0afHGG284pQ3AP61Cn/xVX18f9fX12x174oknCloDAMXz\ngC4AJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLM\nAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANA\nIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJNK26AEkUmn/Tau0vQBl\n8KMNABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIR\nZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgB\nIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIpO8yrVq2Kvn37xtKl\nS/flHgD4p+YeMwAkIswAkMgeh/lPf/pTjBo1Kvr37x/jxo2L1atXR0TEH/7wh/j3f//3GDBgQAwZ\nMiS+//3vR3Nzc8v7/fznP4+RI0fG8ccfH7W1tfHQQw+13HbWWWfFNddcE6NHj44vfvGLrfBlAUBl\n2uMwz5o1K3784x/Hr3/962jXrl1ccsklsXbt2pg4cWKMGTMm/vCHP8TMmTPj/vvvj3vuuSciIh55\n5JH44Q9/GDNmzIhnn3026uvrY/LkybFs2bKWj/vggw/GFVdcETNnzmy1Lw4AKk1VqVQqlfOGq1at\nik9+8pPxne98J/7t3/4tIiIef/zxOOecc+K8886LBQsWxJw5c1re/r/+679i7ty5cffdd8eECRPi\nyCOPjEsuuaTl9nPPPTf69OkTF110UZx11llx6KGHxo9+9KPd7liyYV30fV/nPf06AaAitN3Tdzjq\nqKNaXu7Zs2eUSqV46qmn4qWXXopjjz225bZSqRSHH354RESsWLEifve738VPf/rT7W4/5JBDWl7v\n1q1bWZ+/9v5b93RyYZaPr4/ed8woekbZ+l63segJZZv3/JVR2+/yomeU7ZdzZxU9oWzVXV+O5rV9\nip5Rttpu/YqeULb5zffGydWnFz2jbI3TaoqeULaG+klx1Izrip5Rtob6Sbu8bY/DXF39f2e/37mz\n3b1792jfvn3ccsstO32fDh06xAUXXBATJkzY9ZC2ezwFAA44e/wYc2NjY8vLK1asiDZt2sTRRx8d\nL7/88nZP9lq/fn1s3rw5It6+Z71kyZLtPs6aNWu2e3sA4F2E+a677oq//vWv0dTUFLfffnsMHTo0\nRo8eHU1NTXHDDTfEpk2bYs2aNXHOOefEzTffHBERY8eOjXnz5sUjjzwSb731Vjz77LMxevToeOqp\np1r9CwKASrbHYR47dmx8+ctfjo997GPx1ltvxX/8x39Ex44d48c//nH85je/iUGDBsUXvvCFOPHE\nE+NrX/taRETU1NTElClTYvr06TFgwICYMmVKXHzxxVFTUzmPXwDA/lD2A7s9evRoOR09cuTIHW4/\n6aSTYvbs2bt8/zPOOCPOOOOMnd525513ljsDAA5orvwFAIkIMwAkIswAkIgwA0AiwgwAiQgzACQi\nzACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDAD\nQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJ\nCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLM\nAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANA\nIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkI\nMwAkIswAkIgwA0AibYv4pMOHD49XX301qqt3/H/BlClTYuzYsQWsAoDiFRLmiIhLL700xo0bV9Sn\nB4CUnMoGgESEGQASqSqVSqX9/Un/0WPMzz//fLRp02aX77tkw7ro+77O+3IeABSm4h5jrr3/1n2w\nZt9YPr4+et8xo+gZZet73caiJ5Rt3vNXRm2/y4ueUbZfzp1V9ISyVXd9OZrX9il6Rtlqu/UrekLZ\n5jffGydXn170jLI1TqspekLZGuonxVEzrit6Rtka6ift8jansgEgEWEGgESEGQASKewx5unTp8c1\n11yzw/GhQ4fGjTfeWMAiACheIWH+1a9+VcSnBYD0nMoGgESEGQASEWYASESYASARYQaARIQZABIR\nZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgB\nIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBE\nhBkAEhFmAEhEmAEgEWEGgESqSqVSqegRAMDb3GMGgESEGQASEWYASESYASARYQaARIQZABL5f3br\nq4dr4qqNAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "first head of last state dec_self_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\ni7Vr18bdd98dHTp0iHPOOeeIH/+EE06Ic889NyZPnhx33HHHe/9qAKDCVZVKpVLRIxqiki6mcvFX\n03HxV9OptItoKolj23Qq7dge1cVfAMD7R5gBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYA\nSESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASAR\nYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZ\nABIRZgBIpFXRAxrq3MXXFj2hbOu/WFl7249tU/SEBtkytnfRE8rW9eHK+hm4VedORU8o2/6t24qe\nAI2qsr5bAEAzJ8wAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkI\nMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswA\nkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0Ai\nwgwAiRQa5hUrVsT48ePjzDPPjMGDB8eUKVOipqamyEkAUKhCw3zdddfF6aefHv/xH/8Rjz76aCxf\nvjy+//3vFzkJAApVVSqVSkV98p07d0br1q2jTZs2ERFx6623RnV1dfzjP/7jYd/ntTe2x8n/68T3\nayIAvK9aFfnJly5dGnPmzInq6urYv39/1NbWxoABA/7g+5zzf+97n9YdvfVfnBo95s4qekbZ2r/S\npugJZXv129fHadfdWfSMsnV9eG3RE8r20y2z47wuXyl6Rtn2b91W9ISyLap7JM5ucXHRM5qlSju2\ni+oeOex9hZ3KXrt2bVx77bVxwQUXxJIlS2LZsmUxbty4ouYAQAqFPWJeuXJltGzZMiZMmBBVVVUR\n8c7FYC1auFAcgA+uwip40kknxd69e2P58uVRU1MTs2fPjl27dsX27dujtra2qFkAUKjCwnz66afH\nF7/4xZgwYUKce+650bp167j99tvj7bffdkobgA+sQi/+uummm+Kmm2464LYlS5YUtAYAiucJXQBI\nRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFh\nBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIpFXRAxrqlMm/LnpC+b5YWXur\n2rUrekL5vh3R9eG1Ra8o2+uTehU9oUEqaW9d648WPaFB1t06pOgJZev5t0uLnvCB5BEzACQizACQ\niDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLC\nDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMA\nJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACRSdpg3bdoUJ598cqxevbop9wDAB5pH\nzACQiDADQCINDvN//ud/xujRo6Nfv34xbty42Lx5c0RE/PKXv4y//Mu/jP79+8fQoUPjzjvvjLq6\nuvr3+5d/+ZcYNWpUnH766XHuuefG448/Xn/f+PHjY9asWTFmzJj4q7/6q0b4sgCgMjU4zA8++GB8\n97vfjZ/97GfRunXrmDp1amzdujUmTZoUF110Ufzyl7+MuXPnxk9+8pN4+OGHIyLiqaeeirvuuiu+\n8Y1vxEsvvRQ33XRTTJkyJdauXVv/cR977LGYPn16zJ07t9G+OACoNFWlUqlUzj/ctGlTfOYzn4lv\nfvOb8ed//ucREfHcc8/FFVdcEVdffXUsXrw4FixYUP/v/+mf/ikWLlwYDz30UEycODF69eoVU6dO\nrb//yiuvjN69e8cNN9wQ48ePj+OPPz6+853vHHHHupWbo+cpXRv6dQJARWjV0Hf42Mc+Vv929+7d\no1QqxfPPPx8rV66Mvn371t9XKpXihBNOiIiIDRs2xL//+7/HD37wgwPuP+644+r/u0uXLmV9/is/\nMb2hkwuz8Hf3xmf/+PKiZ5Stql27oieU7adbZsd5Xb5S9IyyvT6pV9ETyvba9Ovj5Bl3Fj2jbHWt\ny3pskcKvp02O3rf/76JnlK3n3y4tekLZFtU9Eme3uLjoGWVbVPfIYe9rcJhbtPifs9/vPtju2rVr\ntGnTJu69995Dvk+7du3i2muvjYkTJx5+SKsGTwGAZqfBzzFXV1fXv71hw4Zo2bJl9OnTJ379618f\ncLHXjh07Yvfu3RHxziPr11577YCPs2XLlgP+PQDwHsI8b968+M1vfhM1NTVx//33x7Bhw2LMmDFR\nU1MT99xzT+zatSu2bNkSV1xxRXzve9+LiIixY8fGE088EU899VTs378/XnrppRgzZkw8//zzjf4F\nAUAla3CYx44dG1/60pfik5/8ZOzfvz/+/u//Ptq3bx/f/e534+c//3kMGjQovvCFL8SZZ54ZV111\nVUREDBkyJKZNmxYzZ86M/v37x7Rp0+LGG2+MIUOGNPoXBACVrOwndrt161Z/OnrUqFEH3X/WWWfF\n/PnzD/v+l1xySVxyySWHvO+BBx4odwYANGte+QsAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASAR\nYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZ\nABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBI\nRJgBIBFhBoBEhBkAEmlV9ICGeuvBDxU9oUEqaW/78f9d9IQGKdXWFT2hbB+5a0XRE8o3vcL2du1c\n9ILyTYvoNe93Ra8oW1XP7kVPaJBWFbb3cDxiBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESY\nASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaA\nRIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIR\nZgBIRJgBIBFhBoBEhBkAEmlVxCcdMWJEbNu2LVq0OPjngmnTpsXYsWMLWAUAxSskzBERN998c4wb\nN66oTw8AKTmVDQCJCDMAJFJVKpVK7/cn/UPPMb/yyivRsmXLw77v2pqt0evYzk05DwAKU3HPMY9b\ncmcTrGkaS8+ZFUOenFr0jLK1H//fRU8o28Jtc+Kzna4qekb59u0tekHZFv7u3vjsH19e9Izyda2c\nH9QXLrs1Ptv3b4ueUbaqnbuKnlC2n77+rTjvozcUPaNsP339W4e9z6lsAEhEmAEgEWEGgEQKe455\n5syZMWvWrINuHzZsWMyePbuARQBQvELC/PTTTxfxaQEgPaeyASARYQaARIQZABIRZgBIRJgBIBFh\nBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhE\nmAEgEWEGgESEGQASEWYASESYASCRqlKpVCp6BADwDo+YASARYQaARIQZABIRZgBIRJgBIBFhBoBE\n/h/ApNjRGeDKBAAAAABJRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "first head of last state dec_enc_attns\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nzACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkEiLogc0Vv3ftSp6QqNU0t7Df1RT\n9IRGqaS9vS88s+gJZZt3R2XtbdGpqugJjdJiwe5FTyjb978zq+gJjTAuqo+vrL3b4hEzACQizACQ\niDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLC\nDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMA\nJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQSJowz5w5M95+++2iZwBAoVKE\nub6+PqZMmSLMAPzN226YBw0aFLNmzWr492mnnRZDhw5t+PfChQujW7duUVtbG2PHjo2+fftG7969\n48wzz4w//elPDe93yCGHxBNPPBEjR46Mr3zlKzFs2LB4/fXXIyKiV69e8f7778fxxx8fv/jFL5ry\n+wOAirLdMPft2zdefvnliPj4ke2CBQti/fr18c4770RExEsvvRQ9evSISy+9NPbYY4949tln48kn\nn4y6urq4+uqrN/tct99+e1x55ZXx3HPPRdu2bePGG2+MiIhHHnkkIj4+nP3jH/+4Sb9BAKgkLbb3\nDv369YsHHnggIiIWLFgQXbp0iX333TfmzZsXQ4YMiZdeein69+8f1dXVERHRqlWraNWqVQwePDju\nv//+zT7XscceG1/4whciIuLrX/96zJw5s9GDb5s+Jr7wxfaN/riizP7dPxc9YZd1V5+7ip5Qvj5F\nD2iceXeML3rCLmvh5HFFT2iEStoaMfGwx4qe0CTKCvNFF10UGzZsiBdffDGOOOKIaN++/WZhrq6u\njvnz58d1110XCxcujI0bN8amTZuiQ4cOm32uTp06Nby92267xYYNGxo9+PTR/6fRH1OU2b/75xjy\n1cuLnlG2/a+rLXpC2e7qc1dUv1Bd9IyyvXprt6InlG3eHeOj1w9/XvSMsq3tVFX0hLItnDwuDr3k\nuqJnlO3735m1/XdKYuJhj8WUBUO3/45J/LX/idjuoezPf/7zsd9++0VNTU28+OKL0atXr+jRo0fM\nmzcvli9fHuvXr4/OnTvHmDFj4vDDD4+nnnoqampqYsKECVt+sWYpzjUDgLTKKmW/fv3ipZdeilde\neSV69uwZX/rSl2LJkiXx29/+Nvr06RNLly6NtWvXxg9/+MPYc889I+Ljw94AQOOUHeZ///d/j/bt\n20fbtm2jRYsWceihh8a9994b/fv3j/322y+aNWsWr7zySqxbty4eeOCBWLJkSbz33nuxfv367X7+\nNm3aRETE0qVLo66ubse+IwCoYGWFuW/fvrF06dLo1atXw209e/aMxYsXx9///d9Hhw4dYsKECXHJ\nJZfEwIEDo7a2Nm644YZo165dHHnkkdv9/HvvvXccddRRMX78+Lj22ms//XcDABVuuyd/RUTstdde\nsXDhws1uGzduXIwb9z9n7FVXVzecmf2JOXPmNLz9yd8sf2LUqFExatSohn/fcMMN5a8GgF2Us7EA\nIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBE\nhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFm\nAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIJEWRQ9orP++uK7oCY1SSXtX\n9qucrbGpsva+89OiFzTOO/+76AXlu/64O4ue0Ajj4qffr5y95957atETyjbxsIi7Zn6r6Bllm3jY\ntu/ziBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhE\nmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEG\ngEQKDfOCBQti9OjR0bt37+jXr19MmDAh6urqipwEAIUqNMw//vGPo3v37vH73/8+HnnkkZg/f37c\ndtttRU4CgEJVlUqlUlFffO3atdGyZcto1apVRERcfvnlsWTJkrjjjju2+TG1/70mDthj389qIgB8\nploU+cWff/75mDp1aixZsiQ++uijqK+vj169ev3VjznpuV98Rut23Nyjroq+T1xQ9Iyy7Xl0bdET\nyjZr0y/jW81OLHpG2Wp/2r/oCWV749zx8cWf/bzoGWW7/ri7ip5Qtm9/sSYefqNb0TPKdu69pxY9\noWyLLhoXB192XdEzyrboonHbvK+wQ9m1tbVxzjnnxLHHHhvPPfdc1NTUxKhRo4qaAwApFPaI+bXX\nXovmzZtHdXV1VFVVRcTHJ4M1a+ZEcQD+dhVWwf333z82btwY8+fPj7q6urjpppti3bp18dZbb0V9\nfX1RswCgUIWFuXv37vGDH/wgqqur46ijjoqWLVvGlVdeGe+//75D2gD8zSr05K8LLrggLrhg85Oj\nnnvuuYLWAEDxPKELAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCI\nMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIM\nAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCIMANAIsIMAIm0KHpA\nYx3U7q2iJzRKJe194cFuRU9olGUVtLfr1A1FTyjfuRFdH62cveM3VBc9oWzfnhQx/v7K2bupdano\nCY1SX2F7t8UjZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZ\nABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBI\nRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIpOwwr1y5\nMg455JBYtGjRztwDAH/TPGIGgESEGQASaXSY//M//zOGDRsWPXr0iFGjRsWqVasiIuKFF16I733v\ne9GzZ88YMGBAXHfddbFp06aGj/u3f/u3GDp0aHTv3j2OOuqoeOyxxxruGz16dFx99dUxfPjw+P73\nv98E3xYAVKZGh/n++++PW265JX7zm99Ey5Yt4/zzz481a9bE2LFjY8SIEfHCCy/EtGnT4uGHH44H\nH3wwIiJmz54d119/fVx11VXx8ssvxwUXXBATJkyI2trahs/76KOPxiWXXBLTpk1rsm8OACpNValU\nKpXzjitXroxvfvObcc0118Q//MM/RETEs88+G6effnqcddZZMWfOnJg5c2bD+991113x+OOPxwMP\nPBBjxoyJAw44IM4///yG+88444w46KCD4txzz43Ro0fHnnvuGTfffPN2d6z4YFXs/3cdG/t9AkBF\naNHYDzjwwAMb3u7cuXOUSqWYO3duvPbaa9GtW7eG+0qlUuy9994REbF8+fL43e9+F/fcc89m9++x\nxx4N/95vv/3K+voTay5u7OTC3NP3jhg194dFzyjbCyu6FD2hbItGXBwHP3Rp0TPK1mlqy6InlO3J\nJyfG4MFTip5RthVDWhc9oWx/nDQ+Drry50XPKNumRheiOLUTxscB11TOz7Z2wvht3tfoH3uzZv9z\n9PuTB9sdO3aMVq1axe23377Vj2nTpk2cc845MWbMmG0PaVFB/wUAwE7S6OeYlyxZ0vD28uXLo3nz\n5nHooYfGH//4x81O9nr77bdj/fr1EfHxI+vXX399s8+zevXqzd4fAPgUYb7vvvviT3/6U9TV1cXd\nd98dAwcOjOHDh0ddXV3ceOONsW7duli9enWcfvrpceutt0ZExMiRI+OJJ56I2bNnx0cffRQvv/xy\nDB8+PObOndvk3xAAVLJGh3nkyJFx6qmnxte+9rX46KOP4l/+5V+ibdu2ccstt8QzzzwTffv2je9+\n97vRu3fv+NGPfhQREf37949JkybFlClTomfPnjFp0qQ477zzon///k3+DQFAJSv7id1OnTo1HI4e\nOnToFvf36dMnZsyYsc2PP+mkk+Kkk07a6n3Tp08vdwYA7NJc+QsAEhFmAEhEmAEgEWEGgESEGQAS\nEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESY\nASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaA\nRIQZABIRZgBIRJgBIBFhBoBEhBkAEmlR9IDGenb+IUVPKF/fytrb4enmRU8o34iIdv/3c0WvKNsH\nHYpe0DgfdGhV9ISyTRwxo+gJjTC+ovZeOuu4oic0Sv3nNhU9oUl4xAwAiQgzACQizACQiDADQCLC\nDACJCDMAJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMA\nJCLMAJCIMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACQizACQiDADQCLCDACJCDMAJCLMAJCI\nMANAIsIMAIkIMwAkIswAkIgwA0AiwgwAiQgzACTSoogvOnjw4HjzzTejWbMt/79g0qRJMXLkyAJW\nAUDxCglzRMTEiRNj1KhRRX15AEjJoWwASESYASCRqlKpVPqsv+hfe475D3/4QzRv3nybH/v6O2/F\nIf9rn505DwAKU3HPMR85866dsGbnWPbDCdHljmuKnlG2Dk9v+3+Isnlh+rnRZ/TPip5RtmYfFb2g\nfL+/79zoN7JyfrZjJs8sekLZTj34d3Hnoq8WPaNsl846rugJZVv6jz+JrjdfW/SMsi39x59s8z6H\nsgEgEWEGgESEGQASKew55ilTpsTVV1+9xe0DBw6Mm266qYBFAFC8QsL85JNPFvFlASA9h7IBIBFh\nBoBEhBkAEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkA\nEhFmAEhEmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIBFhBoBEhBkAEhFmAEhE\nmAEgEWEGgESEGQASEWYASESYASARYQaARIQZABIRZgBIRJgBIJGqUqlUKnoEAPAxj5gBIBFhBoBE\nhBkAEhFmAEhEmAEgEWEGgET+H3PN5Ft3YBfZAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 576x576 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    }
  ]
}